<?php

/**
 * PhpReader Extensible.
 *
 * Helpful methods to read Config file.
 *
 * PHP versions 5
 * CAKEPHP versions 2.x
 * 
 * Green CMS - Content Management System and Framework Powerfull by Cakephp
 * Copyright 2012, GREEN GLOBAL CO., LTD (toancauxanh.vn)
 * 
 * CakePHP(tm) :  Rapid Development Framework (http://www.cakephp.org)
 * Copyright 2005-2011, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * @author        Technology Lab No.I <tech1@toancauxanh.vn>
 * @link          
 * @package       Green.Configure
 * @since         Green v 1.0
 * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
 */

/**
 * PHP Reader allows Configure to load configuration values from
 * files containing simple PHP arrays.
 *
 * Files compatible with PhpReader should define a `$config` variable, that
 * contains all of the configuration data contained in the file.
 */
class PhpReader implements ConfigReaderInterface {

    /**
     * Holds a list of all loaded configuration
     * 
     * @var array
     */
    protected $_loaded = array();

    /**
     * Holds a map configuration keys
     * 
     * @var array
     */
    protected $_map = array(
        'App' => 'app',
        'Model' => 'model',
        'Module' => 'module',
        'Theme' => 'theme'
    );

    /**
     * The path this reader finds files on.
     *
     * @var string
     */
    protected $_path = null;

    /**
     * Constructor for PHP Config file reading.
     *
     * @param string $path The path to read config files from.  Defaults to APP . 'Config' . DS
     */
    public function __construct($path = null, $map = null) {
        if (!$path) {
            $path = TMP . 'config' . DS;
        }
        if ($map) {
            $this->_map = array_merge($this->_map, $map);
        }
        $this->_path = $path;
    }

    /**
     * Returns path of file config , path include name and directory of
     * file in directory App/Tmp/Config/
     *
     * Examples:
     *
     * 	`$ExPhpReader->getPath('Module.System')` will return key of config file run on System plugin startup
     * 	`$ExPhpReader->getPath('App')` will return key of config file run on application startup
     * 	`$ExPhpReader->getPath('Model.Category')` will return key of config file run on Category model startup
     *  `$ExPhpReader->getPath('App.WhenYouNeed')` will return key of config file run on your manual call
     *
     * @param string $name includes type and key of config , it separated by a dot
     * @return string underscored_word of config key
     * @throws ConfigureException
     */
    public function getPath($key) {
        $type = 'App';
        if (strpos($key, '.') !== false) {
            list($type, $key) = explode('.', $key, 2);
            if (!isset($this->_map[$type])) {
                throw new ConfigureException(__d('debug', 'No config type [%s] found', $type));
            }
        } elseif (isset($this->_map[$key])) {
            $type = $key;
            $key = null;
        }
        $type = $this->_map[$type];
        if ($key) {
            $type .= '_' . Inflector::underscore($key);
        }
        return TMP . 'config' . DS . $type . '.php';
    }

    /**
     * load a config file in application directory config and write that into system config
     *
     * @param string $key includes type and key of config , it separated by a dot
     * @param boolean $reload if true the config will load or reload
     * @return an empty array
     * @throws ConfigureException if the path for the config to be loaded is not found
     */
    public function read($key) {
        if (isset($this->_loaded[$key])) {
            return array();
        }
        $path = $this->getPath($key);
        if (!is_file($path)) {
            throw new ConfigureException(__d('debug', 'Could not load configuration file of config %s', $key));
        }
        include $path;
        if (!isset($config) || !is_array($config)) {
            throw new ConfigureException(
                    sprintf(__d('debug', 'No array variable $config found in %s.php'), $file)
            );
        }
        $this->_loaded[$key] = true;
        return $config;
    }

}
